import { ErrorCodes } from '@boticord/consts'
import { CreateReportDto, Report, ResourceComment, ResourceReportStatus } from '@boticord/resources-client'
import { User } from '@boticord/users-client'
import { ConflictException, Injectable, NotFoundException } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'

@Injectable()
export class ReportsService {
  constructor(
    @InjectRepository(Report) private readonly reports: Repository<Report>,
    @InjectRepository(ResourceComment) private readonly comments: Repository<ResourceComment>,
  ) {}

  async getAll() {
    return this.reports.find({ relations: [ 'from', 'resource', 'resource.author' ] })
  }

  async create(from: User, dto: CreateReportDto) {
    const comment = await this.comments.findOne({ where: { id: dto.resourceID } })

    if (comment === null) {
      throw new NotFoundException({ code: ErrorCodes.UnknownComment })
    }

    const existingReport = await this.reports.findOne({
      where: { from: { id: from.id }, resource: { id: comment.id }, status: ResourceReportStatus.Pending },
    })

    if (existingReport !== null) {
      throw new ConflictException({ code: ErrorCodes.AlreadyReported })
    }

    const report = new Report()
    report.from = from
    report.createdAt = Date.now()
    report.content = dto.content
    report.resource = comment

    return await this.reports.save(report)
  }

  async get(id: string) {
    return this.reports.findOne({ where: { id }, relations: [ 'from', 'resource', 'resource.author' ] })
  }

  async changeStatus(id: string, to: ResourceReportStatus) {
    return await this.reports.update({ id }, { status: to })
  }
}
